package hmsai

import (
	"context"
	"hmsDemo/hms.api/webhandler"
	"strings"

	"gitee.com/tgodfather/go-plugins/serviceparam"

	log "gitee.com/tgodfather/misc/logger"

	hmsai "hmsDemo/common/proto/helloworld"

	"github.com/kataras/iris/v12"
	Icontext "github.com/kataras/iris/v12/context"
	"github.com/micro/go-micro/v2/client"
	"go.uber.org/zap"
)

func init() {
	webhandler.RegisterWebPlugin("hmsai", hmsaiWebPluginInit)
}

type hmsaiFuncServiceName func(method string) string
type hmsaiPlugin struct {
	//cfg *config.ServiceConfig
	mapMethod map[string]iris.Handler //内部method map, 用于使用通用处理函数时，通过method 查找对应方法

	client client.Client
	//ServiceName 构建函数
	snFunc hmsaiFuncServiceName
	//call参数
	callOpts []client.CallOption
}

func hmsaiWebPluginInit(wh *webhandler.WebCenter) error {
	vh := newHmsAIPlugin()
	vh.mapMethod = make(map[string]iris.Handler)
	//注册内部map
	vh.registerMethod("carreco", vh.SayHello)

	//注册webHandle map
	wh.RegisterWebHandler("hms.HmsAIService", vh.Handle)
	wh.RegisterWebHandler("hms.HmsAIService.SayHello", vh.SayHello)
	//wh.RegisterWebHandler("hms.HmsAIService.Monitor", vh.Monitor)

	//设置默认路由
	wh.SetHttpRoute("POST", "/hms/v1", "/ai/{method:string}", "hms.HmsAIService")
	//wh.SetHttpRoute("GET", "/hms/v1", "/ai/monitor", "hms.HmsAIService.Monitor")
	//设置client
	vh.client = wh.NewClient()
	vh.snFunc = func(method string) string {
		//return fmt.Sprintf("hms.hmsai", mediaType, strings.ToLower(algoType), strings.ToLower(algoId))
		return "hms.as.hmsai"
	}

	//设置callopt
	vh.callOpts = append(vh.callOpts,
		serviceparam.CallServiceReplace("hmsai")) // grpc_gateway 生成的grpc服务，必须使用proto pacakge的名字
	//client.WithRequestTimeout(60))
	return nil
}

func newHmsAIPlugin() *hmsaiPlugin {
	vh := new(hmsaiPlugin)
	vh.mapMethod = make(map[string]iris.Handler)
	return vh
}

func (h *hmsaiPlugin) registerMethod(method string, f iris.Handler) {
	h.mapMethod[strings.ToLower(method)] = f
}

func (h *hmsaiPlugin) getMethod(method string) (iris.Handler, error) {
	f, ok := h.mapMethod[strings.ToLower(method)]
	if ok {
		return f, nil
	}
	return nil, webhandler.ErrNotFound
}

func (h *hmsaiPlugin) Handle(ctx Icontext.Context) {
	//log.Info("get Request", zap.Reflect("context", ctx))

	ctx.ContentType("application/json")

	method := ctx.Params().GetString("method")
	f, err := h.getMethod(method)

	if nil != err {
		log.Info("get Request error", zap.String("method", method), zap.Error(err))
		//ctx.WriteString("{ErrorCode: 10109, ErrorDescription: 'Method Not Found'}")
		ctx.Writef("{\"ErrorCode\": %d, \"ErrorDescription\": '%s %s'}", webhandler.ErrorCode_MethodNotFound, method, err.Error())
	} else {
		//if body, bodyErr := ctx.GetBody(); nil != bodyErr {
		//	log.Info("get Fie Request ", zap.String("method", method), zap.ByteString("body", body))
		//}
		f(ctx)
	}
}

//func cwF(cf client.CallFunc) client.CallFunc{
//	return func (ctx context.Context, node  *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error {
//		fmt.Printf("===cwF Service[%s] Endpoint[%s] Method[%s] ///////////\b",
//			req.Service(), req.Endpoint(), req.Method())
//
//		return cf(ctx, node , req, rsp, opts)
//	}
//}

func (h *hmsaiPlugin) SayHello(ctx Icontext.Context) {
	//GET the Service
	serviceName := h.snFunc("SayHello")
	c := hmsai.NewGreeterService(serviceName, h.client)

	//Format the Request
	req := &hmsai.HelloRequest{}

	var rsp *hmsai.HelloReply
	rspErr := &hmsai.HelloReply{}
	//err = webhandler.JsonToPb.Unmarshal(httpBody, reqBody)
	err := ctx.UnmarshalBody(req, webhandler.JsonToPb)

	if nil != err {
		log.Error("SayHello Error", zap.Error(err))
		rspErr.Message = err.Error()
		//rspErr.ErrorCode = hmsai.StatusCode_E_PARAM
		rsp = rspErr
	} else {
		//callOpts :=append(h.callOpts, client.WithCallWrapper(cwF))
		rsp, err = c.SayHello(context.TODO(), req, h.callOpts...)
		//rsp, err = c.PictureAnalysis(context.TODO(), req, Filter("haha"))
		//rsp, err = c.PictureAnalysis(context.TODO(), req, WithStrategy())
		if err != nil {
			log.Error("SayHello", zap.Error(err))
			rspErr.Message = err.Error()
			//rspErr.ErrorCode = hmsai.StatusCode_E_COMMON_ERROR
			rsp = rspErr
		}
	}

	//Return the Result
	if err := webhandler.PbToJson.Marshal(ctx, rsp); err != nil {
		ctx.Writef("{\"ErrorCode\": %d, \"ErrorDescription\": '%s'}", webhandler.ErrorCode_Common, err.Error())
	}
}

// func (h *hmsaiPlugin) Monitor(ctx Icontext.Context) {

// 	ctx.ContentType("image/jpeg")

// 	content, _ := ioutil.ReadFile("/mnt/dataL/work/capture/data/2021-05-30/20210530223216.jpg")
// 	ctx.Write(content)
//}
